<?php
/**
 * Created by PhpStorm.
 * User: bolle
 * Date: 25.12.15
 * Time: 09:55
 */

namespace tbollmeier\alteraparser\syntaxgraph;


abstract class VertexGroup implements Dockable
{
    use Clonable;

    private $expanded;
    protected $start;
    protected $end;

    public function __construct()
    {
        $this->expanded = false;
        $this->start = new GroupStartVertex($this);
        $this->end = new GroupEndVertex();
    }

    public function setName($name)
    {
        $res = $this->copy();
        $res->start->name = $name;
        $res->end->name = $name;

        return $res;
    }

    public function getName()
    {
        return $this->start->name;
    }

    public function setId($id)
    {
        $res = $this->copy();
        $res->start->id = $id;
        $res->end->id = $id;

        return $res;
    }

    public function getId()
    {
        return $this->start->id;
    }

    public function transformAst($transformAstFn)
    {
        $res = $this->copy();
        $res->end->transformAstFn = $transformAstFn;

        return $res;
    }

    public function setUnique($unique = true)
    {
        $res = $this->copy();
        $res->end->isEndOfUniqueRule = $unique;

        return $res;
    }

    public function isExpanded()
    {
        return $this->expanded;
    }

    public function expand()
    {
        if ($this->expanded) return;

        $start = new Vertex();
        $end = new Vertex();

        $this->start->connect($start);
        $this->end->connect($end);

        $this->onExpand($start, $end);

        $this->expanded = true;

    }

    abstract protected function onExpand(&$start, &$end);

    public function connect(Dockable $dockable)
    {
        $this->end->connect($dockable);
        return $dockable;
    }

    public function getDockVertex()
    {
        return $this->start;
    }

    protected function onCopy($original)
    {
        $this->start->name = $original->start->name;
        $this->start->id = $original->start->id;

        $this->end->name = $original->end->name;
        $this->end->id = $original->end->id;
        $this->end->transformAstFn = $original->end->transformAstFn;
        $this->end->isEndOfUniqueRule = $original->end->isEndOfUniqueRule;
    }

}